package com.shj.em.biz.finance.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.shj.em.biz.finance.entity.Payment;
import com.shj.em.biz.sell.entity.Order;
import com.shj.em.biz.sell.mapper.OrderMapper;
import com.shj.em.biz.finance.mapper.PaymentMapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import com.baomidou.mybatisplus.plugins.Page;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.shj.em.biz.sys.entity.Cd;
import com.shj.em.biz.sys.mapper.CdMapper;
import com.shj.em.biz.sys.service.CdService;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;


/**
 * 付款信息 服务实现类
 *
 * @author Shen Huang Jian
 * @since 2018-07-13
 */
@Service
@Transactional
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService {

    @Autowired
    PaymentMapper paymentMapper;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    CdMapper cdMapper;

    public List<Payment> getPaymentsByOrderId(Long orderId){
        Wrapper<Payment> wrapper = new EntityWrapper<>();
        wrapper.eq("order_id", orderId);
        wrapper.eq("del_flag", 0);
        return paymentMapper.selectList(wrapper);
    }

    public Page<Payment> queryPaymentPage(Map<String, Object> params){
        int offset = (Integer)params.get("offset");
        int pageSize = (Integer)params.get("limit");
        int pageNo = offset / pageSize + 1;
        Page<Payment> page = new Page(pageNo, pageSize);
        List<Payment> list = paymentMapper.queryPaymentPage(page, params);
        return page.setRecords(list);
    }

    public BigDecimal getUnpaidAmount(Long orderId, Long paymentId){
        Map<String, String> params = new HashMap<String, String>();
        params.put("orderId", orderId + "");
        if(paymentId != null){
            params.put("paymentId", paymentId+"");
        }
        Map<String, BigDecimal> map = this.paymentMapper.getUnpaidAmount(params);
        BigDecimal total = map.get("total");
        BigDecimal paid = map.get("paid");
        if(paid == null){
            return total;
        }else{
            return total.subtract(paid);
        }
    }

    public BigDecimal getTotalPaid(Long orderId){
        Map<String, String> params = new HashMap<String, String>();
        params.put("orderId", orderId+"");
        Map<String, BigDecimal> map = this.paymentMapper.getUnpaidAmount(params);
        BigDecimal paid = map.get("paid");
        if(paid == null){
            return new BigDecimal("0.00");
        }else{
            return paid;
        }
    }

    public Cd createPayment(Payment payment){
        paymentMapper.insert(payment);
        return updateOrderStatus(payment.getOrderId());
    }

    public Cd updatePayment(Payment payment){
        paymentMapper.updateById(payment);
        return updateOrderStatus(payment.getOrderId());
    }

    private Cd updateOrderStatus(Long orderId){
        Order order = orderMapper.selectById(orderId);
        BigDecimal unpaid = getUnpaidAmount(orderId, null);
        int status = unpaid.compareTo(new BigDecimal(0));
        int newStatus = -2;
        if(status == 0){
            newStatus = 2;
            order.setStatus("2");
            order.setCloseFlag(true);
        }else {
            if(unpaid.compareTo(order.getTotalAmount()) == 0){
                newStatus = 0;
                order.setStatus("0");
            }else{
                newStatus = 1;
                order.setStatus("1");
            }
        }
        orderMapper.updateById(order);
        String desc = cdMapper.getDescrByTypeAndCd(CdService.CD_ORDER_STATUS, newStatus+"");
        Cd cd = new Cd();
        cd.setCode(newStatus+"");
        cd. setDescription(desc);
        return cd;
    }

    public Cd deletePaymentById(Long id){
        Payment payment = paymentMapper.selectById(id);
        paymentMapper.deleteById(id);
        return updateOrderStatus(payment.getOrderId());
    }

    public Cd deletePaymentByIds(Long[] ids){
        Payment payment = paymentMapper.selectById(ids[0]);
        deleteBatchIds(Arrays.asList(ids));
        return updateOrderStatus(payment.getOrderId());
    }
}
